﻿using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;
using Mrkz.ImageManipulation;
using Mrkz.ImageManipulation.FrequencyFiltering;
using Mrkz.ImageManipulation.SpatialFiltering;


namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        FFTWindow fftwin1;
        FFTWindow fftwin2;
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {
            ReloadPicture();
        }

        private void cmdLoad_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog of = new Microsoft.Win32.OpenFileDialog();
            of.Filter = "Images|*.jpg;*.png;*.bmp";
            of.Multiselect = false;
            of.CheckFileExists = true;
            of.CheckPathExists = true;

            Nullable<bool> b = of.ShowDialog();

            if (b.HasValue && b.Value)
            {
                Properties.Settings.Default.LastFileName = of.FileName;
                Properties.Settings.Default.Save();
                ReloadPicture();
            }
        }

        private void ReloadPicture()
        {
            if (Properties.Settings.Default.LastFileName.Trim() == "")
                return;

            BitmapImage b = new BitmapImage(new Uri(Properties.Settings.Default.LastFileName));
            imagesrc.Source = b;

        }

        private void cmdTestFilter_Click(object sender, RoutedEventArgs e)
        {
            System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();
            st.Start();
            {
                Mrkz.ImageManipulation.TImage<Pixel> i = ImageFactory<Pixel>.FromBitmapSource(imagesrc.Source as BitmapSource);

                SpatialFilterKernel KR = new IdentityFilterKernel(5);
                SpatialFilterKernel KG = new IdentityFilterKernel(5);
                SpatialFilterKernel KB = new IdentityFilterKernel(5);

                ParametricFilterKernelBase vignette = new PowVignetteFilter(0.7f);              

                SpatialFilterEngine<Pixel> Filter =
                    new SpatialFilterEngine<Pixel>(KR,KB,KG, vignette);

                Mrkz.ImageManipulation.TImage<Pixel> ioutput = Filter.ParallelCalculateFilter(i);

                /*
                 * SpatialFilterKernel K2 = new MotionBlur5();
                MaskFilterBase mask = new LinearVignetteMask();
                SpatialFilterEngine e2 = new SpatialFilterEngine(K2, K2, K2, null, mask);
                ioutput = e2.ParallelCalculateFilter(ioutput);
                */

                WriteableBitmap wb = new WriteableBitmap(imagesrc.Source as BitmapSource);
                InteropImage<Pixel>.WritePixels(ioutput, wb);

                imagedst.Source = wb;
            }
            st.Stop();
            TimeSpan t = st.Elapsed;
            txtElapsed.Content = t.TotalMilliseconds.ToString("N1");
           
        }

        private async Task<TImage<ComplexPixel>> ForwardTransformAsync(Mrkz.ImageManipulation.TImage<Pixel> i)
        {
            FFTEngine engine = new FFTEngine();
            return  await Task.Run<Mrkz.ImageManipulation.TImage<ComplexPixel>>(() => (engine.ForwardTransform(i)));
        }

        private async Task<TImage<Pixel>> InverseTransformAsync(Mrkz.ImageManipulation.TImage<ComplexPixel> i)
        {
            FFTEngine engine = new FFTEngine();
            return await Task.Run<Mrkz.ImageManipulation.TImage<Pixel>>(() => (engine.InverseTransform(i)));          
        }

        private async void cmdTestComplex_Click(object sender, RoutedEventArgs e)
        {
            lblrun.Visibility = System.Windows.Visibility.Visible;
            System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();
            st.Start();
            {
                Mrkz.ImageManipulation.TImage<Pixel> i =ImageFactory<Pixel>.FromBitmapSource(imagesrc.Source as BitmapSource);

                TImage<ComplexPixel> r = await ForwardTransformAsync(i);

                /*WriteableBitmap wb_mag = new WriteableBitmap(imagesrc.Source as BitmapSource);
                WriteableBitmap wb_phase = new WriteableBitmap(imagesrc.Source as BitmapSource);*/

                BitmapSource b = (imagesrc.Source as BitmapSource);
                WriteableBitmap wb_mag = new WriteableBitmap(r.Width, r.Height, b.DpiX, b.DpiY, b.Format, b.Palette);
                WriteableBitmap wb_phase = new WriteableBitmap(r.Width, r.Height, b.DpiX, b.DpiY, b.Format, b.Palette);

                InteropImage<ComplexPixel>.WritePixels(r, wb_mag, wb_phase);

                if (fftwin1 == null)
                {
                    fftwin1 = new FFTWindow();
                    fftwin1.Title = "original FFT";
                }               
                fftwin1.setimg(wb_phase, wb_mag);
                fftwin1.Show();

                ParametricFilterKernelBase vignette = new PowVignetteFilter(0.01f);
                SpatialFilterEngine<ComplexPixel> se = new SpatialFilterEngine<ComplexPixel>(new IdentityFilterKernel(3), vignette);
                TImage<ComplexPixel> r2 = se.ParallelCalculateFilter(r);
                r = r - r2;

                WriteableBitmap wb_mag2 = new WriteableBitmap(r.Width, r.Height, b.DpiX, b.DpiY, b.Format, b.Palette);
                WriteableBitmap wb_phase2 = new WriteableBitmap(r.Width, r.Height, b.DpiX, b.DpiY, b.Format, b.Palette);
                InteropImage<ComplexPixel>.WritePixels(r, wb_mag2, wb_phase2);

                if (fftwin2 == null)
                {
                    fftwin2 = new FFTWindow();
                    fftwin2.Title = "filtered FFT";
                }
                fftwin2.setimg(wb_phase2, wb_mag2);
                fftwin2.Show();

                Mrkz.ImageManipulation.TImage<Pixel> rfinal = await InverseTransformAsync(r);
                WriteableBitmap res = new WriteableBitmap(imagesrc.Source as BitmapSource);
                InteropImage<Pixel>.WritePixels(rfinal,res);

                imagedst.Source = res;

                if (fftwin1 == null)
                    fftwin1 = new FFTWindow();

                fftwin1.setimg(wb_phase, wb_mag);
                fftwin1.Show();
            }
            st.Stop();
            TimeSpan t = st.Elapsed;
            txtElapsed.Content = t.TotalMilliseconds.ToString("N1");

            lblrun.Visibility = System.Windows.Visibility.Hidden;
        }

        private void clos_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (fftwin1 != null)
                fftwin1.Close();
            fftwin1 = null;
        }      

    }
}
